/*
 * ColaClientes.cpp
 *
 *  Created on: Nov 4, 2011
 *      Author: gonzalo
 */

#include "ColaClientes.h"
#include "../common/utils/Logger.h"

ColaClientes::ColaClientes() {

}

ColaClientes::~ColaClientes() {
	std::list<ConexionServer*>::iterator it = this->clientes.begin();
	while (it != this->clientes.end())
	{
		delete(*it);
		++it;
	}
}


void ColaClientes::setClient(ConexionServer* cliente){
	Logger::log("ColaClientes", "setClient","Recibio un nuevo cliente" );
	clientes.push_back(cliente);

	signal();
}

ConexionServer* ColaClientes::getClient(){
	Logger::log("ColaClientes", "getCliente","Pide un cliente" );


	//Si la Lista esta vacia me quedo bloqueado hasta que llegue una senial
	if (clientes.empty()) {
		wait();
	}

	ConexionServer* retorno = clientes.front();
	clientes.pop_front();

	return retorno;
}


void ColaClientes::limpiarDesconectados(){
	ConexionServer* connectedClient;

	std::list<ConexionServer*> aRemover;

	std::list<ConexionServer*>::iterator it_aux;
	for (it_aux = clientes.begin(); it_aux != clientes.end();
			++it_aux) {
		connectedClient = (*it_aux);

		//Verifico que este caido el cliente
		if (!connectedClient->isConnected()) {
			aRemover.push_back(connectedClient);
		}
	}


	std::list<DTOCliente*> aPropagar;
	//Tengo todos los clientes a remover del servidor
	while(!aRemover.empty()){
		connectedClient = aRemover.back();
		aRemover.pop_back();

		std::string clientDesconectado = connectedClient->getClienteId();

		//Lo elimino de la lista del servidor
		connectedClient->terminar();
		this->clientes.remove(connectedClient);
//		delete connectedClient;

		//Informo la desconexion
		aPropagar.push_back(new DTOCliente(SERVER_OWN,clientDesconectado,DISCONECTED));
	}

	while(!aPropagar.empty()){
		propagarDTO(aPropagar.back());
		aPropagar.pop_back();
	}

}

void ColaClientes::propagarDTO(DTO* dto){
	ConexionServer* connectedClient;

	std::list<ConexionServer*>::iterator it_aux;
	for (it_aux = clientes.begin(); it_aux != clientes.end();
			++it_aux) {
		connectedClient = (*it_aux);

		//Verifico que no este caido el cliente a ultimo momento
		if (connectedClient->isConnected()) {
			connectedClient->addToSend(dto);
		}
	}
}

int ColaClientes::getSize(){
	return this->clientes.size();
}

void ColaClientes::terminar(){
	ConexionServer* aux;

	std::list<ConexionServer*>::iterator it_aux;
	for (it_aux = clientes.begin(); it_aux != clientes.end();
			++it_aux) {
		aux = (*it_aux);
		aux->terminar();
	}
}


